---
title: "Example: Database-Specific Configurations | RAG"
description: Learn how to use database-specific configurations to optimize vector search performance and leverage unique features of different vector stores.
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Database-Specific Configurations

This example demonstrates how to use database-specific configurations with vector query tools to optimize performance and leverage unique features of different vector stores.

## Multi-Environment Setup

Use different configurations for different environments:

<Tabs>
  <TabItem value="typescript" label="TypeScript">

```typescript
import { createVectorQueryTool } from "@mastra/rag";
import { RequestContext } from "@mastra/core/request-context";
import { ModelRouterEmbeddingModel } from "@mastra/core/llm";

// Base configuration
const createSearchTool = (environment: "dev" | "staging" | "prod") => {
  return createVectorQueryTool({
    vectorStoreName: "pinecone",
    indexName: "documents",
    model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
    databaseConfig: {
      pinecone: {
        namespace: environment,
      },
    },
  });
};

// Create environment-specific tools
const devSearchTool = createSearchTool("dev");
const prodSearchTool = createSearchTool("prod");

// Or use runtime override
const dynamicSearchTool = createVectorQueryTool({
  vectorStoreName: "pinecone",
  indexName: "documents",
  model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
});

// Switch environment at runtime
const switchEnvironment = async (environment: string, query: string) => {
  const requestContext = new RequestContext();
  requestContext.set("databaseConfig", {
    pinecone: {
      namespace: environment,
    },
  });

  return await dynamicSearchTool.execute({
    context: { queryText: query },
    mastra,
    requestContext,
  });
};
```

  </TabItem>
  <TabItem value="javascript" label="JavaScript">

```javascript
import { createVectorQueryTool } from "@mastra/rag";
import { RequestContext } from "@mastra/core/request-context";

// Base configuration
const createSearchTool = (environment) => {
  return createVectorQueryTool({
    vectorStoreName: "pinecone",
    indexName: "documents",
    model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
    databaseConfig: {
      pinecone: {
        namespace: environment,
      },
    },
  });
};

// Create environment-specific tools
const devSearchTool = createSearchTool("dev");
const prodSearchTool = createSearchTool("prod");

// Or use runtime override
const dynamicSearchTool = createVectorQueryTool({
  vectorStoreName: "pinecone",
  indexName: "documents",
  model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
});

// Switch environment at runtime
const switchEnvironment = async (environment, query) => {
  const requestContext = new RequestContext();
  requestContext.set("databaseConfig", {
    pinecone: {
      namespace: environment,
    },
  });

  return await dynamicSearchTool.execute({
    context: { queryText: query },
    mastra,
    requestContext,
  });
};
```

  </TabItem>
</Tabs>

## Performance Optimization with pgVector

Optimize search performance for different use cases:

<Tabs>
  <TabItem value="high-accuracy" label="High Accuracy">

```typescript
import { ModelRouterEmbeddingModel } from "@mastra/core/llm";

// High accuracy configuration - slower but more precise
const highAccuracyTool = createVectorQueryTool({
  vectorStoreName: "postgres",
  indexName: "embeddings",
  model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
  databaseConfig: {
    pgvector: {
      ef: 400, // High accuracy for HNSW
      probes: 20, // High recall for IVFFlat
      minScore: 0.85, // High quality threshold
    },
  },
});

// Use for critical searches where accuracy is paramount
const criticalSearch = async (query: string) => {
  return await highAccuracyTool.execute({
    context: {
      queryText: query,
      topK: 5, // Fewer, higher quality results
    },
    mastra,
  });
};
```

  </TabItem>
  <TabItem value="high-speed" label="High Speed">

```typescript
import { ModelRouterEmbeddingModel } from "@mastra/core/llm";

// High speed configuration - faster but less precise
const highSpeedTool = createVectorQueryTool({
  vectorStoreName: "postgres",
  indexName: "embeddings",
  model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
  databaseConfig: {
    pgvector: {
      ef: 50, // Lower accuracy for speed
      probes: 3, // Lower recall for speed
      minScore: 0.6, // Lower quality threshold
    },
  },
});

// Use for real-time applications
const realtimeSearch = async (query: string) => {
  return await highSpeedTool.execute({
    context: {
      queryText: query,
      topK: 10, // More results to compensate for lower precision
    },
    mastra,
  });
};
```

  </TabItem>
  <TabItem value="balanced" label="Balanced">

```typescript
import { ModelRouterEmbeddingModel } from "@mastra/core/llm";

// Balanced configuration - good compromise
const balancedTool = createVectorQueryTool({
  vectorStoreName: "postgres",
  indexName: "embeddings",
  model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
  databaseConfig: {
    pgvector: {
      ef: 150, // Moderate accuracy
      probes: 8, // Moderate recall
      minScore: 0.7, // Moderate quality threshold
    },
  },
});

// Adjust parameters based on load
const adaptiveSearch = async (query: string, isHighLoad: boolean) => {
  const requestContext = new RequestContext();

  if (isHighLoad) {
    // Reduce quality for speed during high load
    requestContext.set("databaseConfig", {
      pgvector: {
        ef: 75,
        probes: 5,
        minScore: 0.65,
      },
    });
  }

  return await balancedTool.execute({
    context: { queryText: query },
    mastra,
    requestContext,
  });
};
```

  </TabItem>
</Tabs>

## Multi-Tenant Application with Pinecone

Implement tenant isolation using Pinecone namespaces:

```typescript
import { ModelRouterEmbeddingModel } from "@mastra/core/llm";

interface Tenant {
  id: string;
  name: string;
  namespace: string;
}

class MultiTenantSearchService {
  private searchTool: RagTool;

  constructor() {
    this.searchTool = createVectorQueryTool({
      vectorStoreName: "pinecone",
      indexName: "shared-documents",
      model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
    });
  }

  async searchForTenant(tenant: Tenant, query: string) {
    const requestContext = new RequestContext();

    // Isolate search to tenant's namespace
    requestContext.set("databaseConfig", {
      pinecone: {
        namespace: tenant.namespace,
      },
    });

    const results = await this.searchTool.execute({
      context: {
        queryText: query,
        topK: 10,
      },
      mastra,
      requestContext,
    });

    // Add tenant context to results
    return {
      tenant: tenant.name,
      query,
      results: results.relevantContext,
      sources: results.sources,
    };
  }

  async bulkSearchForTenants(tenants: Tenant[], query: string) {
    const promises = tenants.map((tenant) =>
      this.searchForTenant(tenant, query),
    );

    return await Promise.all(promises);
  }
}

// Usage
const searchService = new MultiTenantSearchService();

const tenants = [
  { id: "1", name: "Company A", namespace: "company-a" },
  { id: "2", name: "Company B", namespace: "company-b" },
];

const results = await searchService.searchForTenant(
  tenants[0],
  "product documentation",
);
```

## Hybrid Search with Pinecone

Combine semantic and keyword search:

```typescript
import { ModelRouterEmbeddingModel } from "@mastra/core/llm";

const hybridSearchTool = createVectorQueryTool({
  vectorStoreName: "pinecone",
  indexName: "documents",
  model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
  databaseConfig: {
    pinecone: {
      namespace: "production",
      sparseVector: {
        // Example sparse vector for keyword "API"
        indices: [1, 5, 10, 15],
        values: [0.8, 0.6, 0.4, 0.2],
      },
    },
  },
});

// Helper function to generate sparse vectors for keywords
const generateSparseVector = (keywords: string[]) => {
  // This is a simplified example - in practice, you'd use
  // a proper sparse encoding method like BM25
  const indices: number[] = [];
  const values: number[] = [];

  keywords.forEach((keyword, i) => {
    const hash = keyword.split("").reduce((a, b) => {
      a = (a << 5) - a + b.charCodeAt(0);
      return a & a;
    }, 0);

    indices.push(Math.abs(hash) % 1000);
    values.push(1.0 / (i + 1)); // Decrease weight for later keywords
  });

  return { indices, values };
};

const hybridSearch = async (query: string, keywords: string[]) => {
  const requestContext = new RequestContext();

  if (keywords.length > 0) {
    const sparseVector = generateSparseVector(keywords);
    requestContext.set("databaseConfig", {
      pinecone: {
        namespace: "production",
        sparseVector,
      },
    });
  }

  return await hybridSearchTool.execute({
    context: { queryText: query },
    mastra,
    requestContext,
  });
};

// Usage
const results = await hybridSearch("How to use the REST API", [
  "API",
  "REST",
  "documentation",
]);
```

## Quality-Gated Search

Implement progressive search quality:

```typescript
const createQualityGatedSearch = () => {
  const baseConfig = {
    vectorStoreName: "postgres",
    indexName: "embeddings",
    model: new ModelRouterEmbeddingModel("openai/text-embedding-3-small"),
  };

  return {
    // High quality search first
    highQuality: createVectorQueryTool({
      ...baseConfig,
      databaseConfig: {
        pgvector: {
          minScore: 0.85,
          ef: 200,
          probes: 15,
        },
      },
    }),

    // Medium quality fallback
    mediumQuality: createVectorQueryTool({
      ...baseConfig,
      databaseConfig: {
        pgvector: {
          minScore: 0.7,
          ef: 150,
          probes: 10,
        },
      },
    }),

    // Low quality last resort
    lowQuality: createVectorQueryTool({
      ...baseConfig,
      databaseConfig: {
        pgvector: {
          minScore: 0.5,
          ef: 100,
          probes: 5,
        },
      },
    }),
  };
};

const progressiveSearch = async (query: string, minResults: number = 3) => {
  const tools = createQualityGatedSearch();

  // Try high quality first
  let results = await tools.highQuality.execute({
    context: { queryText: query },
    mastra,
  });

  if (results.sources.length >= minResults) {
    return { quality: "high", ...results };
  }

  // Fallback to medium quality
  results = await tools.mediumQuality.execute({
    context: { queryText: query },
    mastra,
  });

  if (results.sources.length >= minResults) {
    return { quality: "medium", ...results };
  }

  // Last resort: low quality
  results = await tools.lowQuality.execute({
    context: { queryText: query },
    mastra,
  });

  return { quality: "low", ...results };
};

// Usage
const results = await progressiveSearch("complex technical query", 5);
console.log(
  `Found ${results.sources.length} results with ${results.quality} quality`,
);
```

## Key Takeaways

1. **Environment Isolation**: Use namespaces to separate data by environment or tenant
2. **Performance Tuning**: Adjust ef/probes parameters based on your accuracy vs speed requirements
3. **Quality Control**: Use minScore to filter out low-quality matches
4. **Runtime Flexibility**: Override configurations dynamically based on context
5. **Progressive Quality**: Implement fallback strategies for different quality levels

This approach allows you to optimize vector search for your specific use case while maintaining flexibility and performance.
